/**
 * 依赖注入容器
 * 
 * 职责：
 * 1. 管理所有服务的注册和实例化
 * 2. 支持单例、瞬态、作用域生命周期
 * 3. 自动依赖解析和注入
 * 4. 循环依赖检测
 * 5. 支持工厂函数和类注册
 * 
 * @author AI Assistant
 * @date 2025-11-27
 */

import { Log } from '../logger/LoggerGlobal';

/**
 * 服务生命周期
 */
export enum ServiceLifetime {
    /** 单例 - 全局唯一实例 */
    SINGLETON = 'singleton',
    /** 瞬态 - 每次请求创建新实例 */
    TRANSIENT = 'transient',
    /** 作用域 - 在同一作用域内共享实例 */
    SCOPED = 'scoped'
}

/**
 * 服务标识符类型
 */
export type ServiceIdentifier<T = any> = string | symbol | (new (...args: any[]) => T);

/**
 * 服务工厂函数
 */
export type ServiceFactory<T = any> = (container: DIContainer) => T;

/**
 * 服务构造函数
 */
export type ServiceConstructor<T = any> = new (...args: any[]) => T;

/**
 * 服务描述符
 */
interface ServiceDescriptor<T = any> {
    /** 服务标识符 */
    identifier: ServiceIdentifier<T>;
    /** 生命周期 */
    lifetime: ServiceLifetime;
    /** 实现类型（构造函数或工厂函数）*/
    implementation: ServiceConstructor<T> | ServiceFactory<T>;
    /** 单例实例（仅用于 SINGLETON）*/
    instance?: T;
    /** 依赖项 */
    dependencies?: ServiceIdentifier[];
}

/**
 * 依赖注入容器
 */
export class DIContainer {
    /** 服务描述符映射 */
    private services: Map<ServiceIdentifier, ServiceDescriptor> = new Map();
    
    /** 作用域实例缓存 */
    private scopedInstances: Map<ServiceIdentifier, any> = new Map();
    
    /** 当前解析栈（用于循环依赖检测）*/
    private resolvingStack: ServiceIdentifier[] = [];
    
    /** 是否启用日志 */
    private enableLog: boolean = false;
    
    /**
     * 构造函数
     */
    constructor(enableLog: boolean = false) {
        this.enableLog = enableLog;
    }
    
    // ============================================================================
    // 服务注册
    // ============================================================================
    
    /**
     * 注册单例服务
     */
    registerSingleton<T>(
        identifier: ServiceIdentifier<T>,
        implementation: ServiceConstructor<T> | ServiceFactory<T>,
        dependencies?: ServiceIdentifier[]
    ): this {
        return this.register(identifier, implementation, ServiceLifetime.SINGLETON, dependencies);
    }
    
    /**
     * 注册瞬态服务
     */
    registerTransient<T>(
        identifier: ServiceIdentifier<T>,
        implementation: ServiceConstructor<T> | ServiceFactory<T>,
        dependencies?: ServiceIdentifier[]
    ): this {
        return this.register(identifier, implementation, ServiceLifetime.TRANSIENT, dependencies);
    }
    
    /**
     * 注册作用域服务
     */
    registerScoped<T>(
        identifier: ServiceIdentifier<T>,
        implementation: ServiceConstructor<T> | ServiceFactory<T>,
        dependencies?: ServiceIdentifier[]
    ): this {
        return this.register(identifier, implementation, ServiceLifetime.SCOPED, dependencies);
    }
    
    /**
     * 注册服务
     */
    private register<T>(
        identifier: ServiceIdentifier<T>,
        implementation: ServiceConstructor<T> | ServiceFactory<T>,
        lifetime: ServiceLifetime,
        dependencies?: ServiceIdentifier[]
    ): this {
        const identifierKey = this.getIdentifierKey(identifier);
        
        if (this.services.has(identifierKey)) {
            Log.general.warn('服务已注册，将被覆盖', {
                identifier: this.getIdentifierName(identifier)
            });
        }
        
        this.services.set(identifierKey, {
            identifier,
            lifetime,
            implementation,
            dependencies: dependencies || []
        });
        
        if (this.enableLog) {
            Log.general.debug('注册服务', {
                identifier: this.getIdentifierName(identifier),
                lifetime
            });
        }
        
        return this;
    }
    
    /**
     * 注册实例（直接注册已创建的实例）
     */
    registerInstance<T>(identifier: ServiceIdentifier<T>, instance: T): this {
        const identifierKey = this.getIdentifierKey(identifier);
        
        this.services.set(identifierKey, {
            identifier,
            lifetime: ServiceLifetime.SINGLETON,
            implementation: (() => instance) as ServiceFactory<T>,
            instance
        });
        
        if (this.enableLog) {
            Log.general.debug('注册实例', {
                identifier: this.getIdentifierName(identifier)
            });
        }
        
        return this;
    }
    
    // ============================================================================
    // 服务解析
    // ============================================================================
    
    /**
     * 解析服务
     */
    resolve<T>(identifier: ServiceIdentifier<T>): T {
        const identifierKey = this.getIdentifierKey(identifier);
        const descriptor = this.services.get(identifierKey);
        
        if (!descriptor) {
            throw new Error(
                `服务未注册: ${this.getIdentifierName(identifier)}`
            );
        }
        
        // 检查循环依赖
        if (this.resolvingStack.includes(identifierKey)) {
            const cycle = [...this.resolvingStack, identifierKey]
                .map(id => this.getIdentifierName(id))
                .join(' -> ');
            throw new Error(`检测到循环依赖: ${cycle}`);
        }
        
        // 添加到解析栈
        this.resolvingStack.push(identifierKey);
        
        try {
            let instance: T;
            
            switch (descriptor.lifetime) {
                case ServiceLifetime.SINGLETON:
                    instance = this.resolveSingleton(descriptor);
                    break;
                    
                case ServiceLifetime.SCOPED:
                    instance = this.resolveScoped(descriptor);
                    break;
                    
                case ServiceLifetime.TRANSIENT:
                    instance = this.resolveTransient(descriptor);
                    break;
                    
                default:
                    throw new Error(`未知的生命周期: ${descriptor.lifetime}`);
            }
            
            return instance;
        } finally {
            // 从解析栈移除
            this.resolvingStack.pop();
        }
    }
    
    /**
     * 解析单例
     */
    private resolveSingleton<T>(descriptor: ServiceDescriptor<T>): T {
        if (descriptor.instance) {
            return descriptor.instance;
        }
        
        const instance = this.createInstance(descriptor);
        descriptor.instance = instance;
        
        if (this.enableLog) {
            Log.general.debug('创建单例实例', {
                identifier: this.getIdentifierName(descriptor.identifier)
            });
        }
        
        return instance;
    }
    
    /**
     * 解析作用域服务
     */
    private resolveScoped<T>(descriptor: ServiceDescriptor<T>): T {
        const identifierKey = this.getIdentifierKey(descriptor.identifier);
        
        if (this.scopedInstances.has(identifierKey)) {
            return this.scopedInstances.get(identifierKey);
        }
        
        const instance = this.createInstance(descriptor);
        this.scopedInstances.set(identifierKey, instance);
        
        if (this.enableLog) {
            Log.general.debug('创建作用域实例', {
                identifier: this.getIdentifierName(descriptor.identifier)
            });
        }
        
        return instance;
    }
    
    /**
     * 解析瞬态服务
     */
    private resolveTransient<T>(descriptor: ServiceDescriptor<T>): T {
        const instance = this.createInstance(descriptor);
        
        if (this.enableLog) {
            Log.general.debug('创建瞬态实例', {
                identifier: this.getIdentifierName(descriptor.identifier)
            });
        }
        
        return instance;
    }
    
    /**
     * 创建实例
     */
    private createInstance<T>(descriptor: ServiceDescriptor<T>): T {
        const { implementation } = descriptor;
        
        // 工厂函数
        if (typeof implementation === 'function' && implementation.length === 1) {
            return (implementation as ServiceFactory<T>)(this);
        }
        
        // 构造函数
        if (typeof implementation === 'function') {
            const Constructor = implementation as ServiceConstructor<T>;
            
            // 解析依赖
            const dependencies = (descriptor.dependencies || []).map(dep =>
                this.resolve(dep)
            );
            
            return new Constructor(...dependencies);
        }
        
        throw new Error(
            `无效的服务实现: ${this.getIdentifierName(descriptor.identifier)}`
        );
    }
    
    // ============================================================================
    // 作用域管理
    // ============================================================================
    
    /**
     * 创建子作用域
     */
    createScope(): DIContainer {
        const scope = new DIContainer(this.enableLog);
        
        // 复制服务描述符
        for (const [key, descriptor] of this.services) {
            scope.services.set(key, { ...descriptor });
        }
        
        if (this.enableLog) {
            Log.general.debug('创建子作用域');
        }
        
        return scope;
    }
    
    /**
     * 清除作用域实例
     */
    clearScope(): void {
        this.scopedInstances.clear();
        
        if (this.enableLog) {
            Log.general.debug('清除作用域实例');
        }
    }
    
    // ============================================================================
    // 工具方法
    // ============================================================================
    
    /**
     * 检查服务是否已注册
     */
    has(identifier: ServiceIdentifier): boolean {
        return this.services.has(this.getIdentifierKey(identifier));
    }
    
    /**
     * 注销服务
     */
    unregister(identifier: ServiceIdentifier): void {
        const identifierKey = this.getIdentifierKey(identifier);
        const descriptor = this.services.get(identifierKey);
        
        if (descriptor) {
            // 销毁单例实例
            if (descriptor.instance && typeof (descriptor.instance as any).destroy === 'function') {
                (descriptor.instance as any).destroy();
            }
            
            this.services.delete(identifierKey);
            
            if (this.enableLog) {
                Log.general.debug('注销服务', {
                    identifier: this.getIdentifierName(identifier)
                });
            }
        }
    }
    
    /**
     * 清除所有服务
     */
    clear(): void {
        // 销毁所有单例实例
        for (const descriptor of this.services.values()) {
            if (descriptor.instance && typeof (descriptor.instance as any).destroy === 'function') {
                (descriptor.instance as any).destroy();
            }
        }
        
        this.services.clear();
        this.scopedInstances.clear();
        
        if (this.enableLog) {
            Log.general.info('清除所有服务');
        }
    }
    
    /**
     * 获取标识符的键
     */
    private getIdentifierKey(identifier: ServiceIdentifier): ServiceIdentifier {
        if (typeof identifier === 'function') {
            return identifier.name || identifier;
        }
        return identifier;
    }
    
    /**
     * 获取标识符的名称（用于日志）
     */
    private getIdentifierName(identifier: ServiceIdentifier | string | symbol): string {
        if (typeof identifier === 'string') {
            return identifier;
        }
        if (typeof identifier === 'symbol') {
            return identifier.toString();
        }
        if (typeof identifier === 'function') {
            return identifier.name || 'Anonymous';
        }
        return String(identifier);
    }
    
    /**
     * 获取统计信息
     */
    getStatistics() {
        const stats = {
            totalServices: this.services.size,
            singletonCount: 0,
            transientCount: 0,
            scopedCount: 0,
            instancedSingletons: 0,
            services: [] as Array<{
                identifier: string;
                lifetime: ServiceLifetime;
                hasInstance: boolean;
            }>
        };
        
        for (const descriptor of this.services.values()) {
            switch (descriptor.lifetime) {
                case ServiceLifetime.SINGLETON:
                    stats.singletonCount++;
                    if (descriptor.instance) {
                        stats.instancedSingletons++;
                    }
                    break;
                case ServiceLifetime.TRANSIENT:
                    stats.transientCount++;
                    break;
                case ServiceLifetime.SCOPED:
                    stats.scopedCount++;
                    break;
            }
            
            stats.services.push({
                identifier: this.getIdentifierName(descriptor.identifier),
                lifetime: descriptor.lifetime,
                hasInstance: !!descriptor.instance
            });
        }
        
        return stats;
    }
    
    /**
     * 打印统计信息
     */
    printStatistics(): void {
        const stats = this.getStatistics();
        
        Log.styled('━'.repeat(60), 'separator');
        Log.styled('📦 DI 容器统计信息', 'title');
        Log.styled('━'.repeat(60), 'separator');
        
        Log.general.info(`总服务数: ${stats.totalServices}`);
        Log.general.info(`单例服务: ${stats.singletonCount} (已实例化: ${stats.instancedSingletons})`);
        Log.general.info(`瞬态服务: ${stats.transientCount}`);
        Log.general.info(`作用域服务: ${stats.scopedCount}`);
        
        if (stats.services.length > 0) {
            Log.styled('📋 已注册的服务', 'large');
            for (const service of stats.services) {
                const instanceStatus = service.hasInstance ? '✓' : '○';
                Log.general.info(
                    `  ${instanceStatus} ${service.identifier} (${service.lifetime})`
                );
            }
        }
        
        Log.styled('━'.repeat(60), 'separator');
    }
}

/**
 * 全局 DI 容器实例
 */
export const container = new DIContainer(false);

/**
 * 配置全局容器
 */
export function configureContainer(enableLog: boolean = false): void {
    (container as any).enableLog = enableLog;
}

